package pip

import (
	"encoding/json"
	"fmt"
	"log"
	"sync"
	"time"
)

type ElementType struct {
	Name string
	Age  int64
}

func (e *ElementType) String() string {
	bytes, _ := json.Marshal(e)
	return string(bytes)
}

type FilterType int32

func (ft FilterType) String() string {
	switch ft {
	case 1:
		return "BaseInfo"
	default:
		return "NotSupportFilterType"
	}
}

const (
	FilterBaseInfo FilterType = iota + 1
	FilterChildren
)

type FilterPipelineHandler struct {
	filter     FilterPipeline
	flag       string //标记 pipline 的名称，用于debug
	filterList []ElementFilter
}

func NewFilterPipelineHandler(filter FilterPipeline, flag string) *FilterPipelineHandler {
	return &FilterPipelineHandler{
		filter: filter,
		flag:   flag,
	}
}

func (h *FilterPipelineHandler) Name() string {
	return "FilterPipelineHandler_" + h.flag
}

func (h *FilterPipelineHandler) PipeProcess(ctx *RPipeContext) {
	lastTime := time.Now().UnixNano()

	beforeFilterList := ctx.Ctx.CandidateList
	//filter
	err := Filter(h.filter, ctx.Ctx)

	filterCost := time.Now().UnixNano() - lastTime
	afterFilterList := ctx.Ctx.CandidateList

	log.Println(h.flag+"_filter_total_count", fmt.Sprintf("%v", len(beforeFilterList)-len(afterFilterList)))
	log.Println("filter_total_cost_"+h.flag, filterCost)

	if err != nil {
		log.Printf("FilterPipelineHandler_fail||action=filterPipeProcess||_msg=do filter failed||err=%v", err)
	}
	return
}

// Filter 过滤入口函数
func Filter(pipeline FilterPipeline, ctx *SimpleContext) error {
	//可以在定义一个filter context 把 simplecontext里边的数据抽取一下，简化内容 或者扩展内容
	filterContext := NewFilterContext(ctx)
	newCandidateList, filterResult, err := pipeline.execHandlerFilter(filterContext, ctx.CandidateList)
	if err != nil {
		return err
	}
	for filterType := range filterResult.FilterResult {
		//记录信息，可自定义扩展
		log.Printf("filterType=%v,filter_count=%v\n", filterType, len(filterResult.FilterResult[filterType]))
	}
	ctx.CandidateList = newCandidateList
	return nil
}

//扩展的filterpipline

type filterHandlerEntity struct {
	handler FilterHandler
	name    string
}

type defaultFilterPipeline struct {
	filterHandlerList []filterHandlerEntity
	eleFeature        []int
	lock              sync.Mutex
}

func (p *defaultFilterPipeline) addFeature(shopFeature ...int) FilterPipeline {
	p.eleFeature = append(p.eleFeature, shopFeature...)
	return p
}

func (p *defaultFilterPipeline) addLast(name string, handler FilterHandler) FilterPipeline {
	p.filterHandlerList = append(p.filterHandlerList, filterHandlerEntity{handler: handler, name: name})
	return p
}

func (p *defaultFilterPipeline) execHandlerFilter(ctx *FilterContext, candidateList []ElementType) (resultList []ElementType, filterResult *FilterResult, err error) {

	for i := range candidateList {
		resultList = append(resultList, candidateList[i])
	}
	//todo 在执行过滤执行可以 做别的事情，获取信息，填充数据什么的

	filterResult = NewFilterResult()
	total := len(resultList)
	// 顺序执行过滤

	begTime2 := time.Now().UnixNano()
	for i := range p.filterHandlerList {
		beg := time.Now()
		handler := p.filterHandlerList[i].handler
		afterFilterResultList, tmpFilterResult, err := handler.Filter(ctx, resultList)
		// 计算本步骤过滤掉了多少条目
		filterd := len(resultList) - len(afterFilterResultList)
		filteredrate := float32(filterd) / float32(total) * 100

		log.Printf("defaultFilterPipeline_Filter||filtername=%s||cost=%v||filtered=%d||filteredrate=%f||filterResult=%v||err=%v",
			p.filterHandlerList[i].name, time.Since(beg), filterd, filteredrate, tmpFilterResult, err)

		if err != nil {
			return resultList, filterResult, err
		}
		filterResult.merge(tmpFilterResult)
		resultList = afterFilterResultList
	}
	log.Println("filter_function_cost", time.Now().UnixNano()-begTime2)
	log.Printf("_soda_recsys_broker_defaultFilterPipeline_Filter||action=printPipelineFilterResult||filterResult=%v", filterResult)
	return
}
